package search.lucene;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

/**
 *
 * @author cosmin
 */
public class Abstract {

    protected StandardAnalyzer _analyzer;
    protected Directory _directory;
    protected IndexReader _indexReader;
    protected IndexSearcher _indexSearcher;
    protected boolean isIndexerOpen;
    public int hitsPerPage = 1000000;
    public ScoreDoc[] hits;
    public int totalHits = 0;
    public boolean hasResults;

    public Abstract() {
        this.isIndexerOpen = false;
        this.hasResults = false;
        this.openIndexer();
    }

    private void openIndexer() {
        if (!this.isIndexerOpen) {
            try {
                this._analyzer = new StandardAnalyzer(Version.LUCENE_40);
                this._directory = FSDirectory.open(new File("index"));
                this._indexReader = DirectoryReader.open(this._directory);
                this._indexSearcher = new IndexSearcher(this._indexReader);
                this.isIndexerOpen = true;
            } catch (IOException ex) {
                Logger.getLogger(Query.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void closeIndexer() {
        if (this.isIndexerOpen) {
            try {
                this._indexReader.close();
            } catch (IOException ex) {
                Logger.getLogger(Query.class.getName()).log(Level.SEVERE, null, ex);
            }
            this.isIndexerOpen = false;
        }
    }

    public int countHits() {
        if (this.hasResults) {
            return this.totalHits;
        }
        return 0;
    }

    public List<Document> getDocuments() {
        List<Document> result = new ArrayList<Document>();
        if (this.hasResults) {
            for (int i = 0; i < hits.length; ++i) {
                int docId = this.hits[i].doc;
                try {
                    Document d = this._indexSearcher.doc(docId);
                    result.add(d);
                } catch (IOException ex) {
                    Logger.getLogger(Abstract.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        return result;
    }

    public Document getByUrl(String url) {
        Document document = null;
        try {
            org.apache.lucene.search.Query q = new QueryParser(Version.LUCENE_40, "url", this._analyzer).parse(QueryParser.escape(url));
            TopScoreDocCollector collector = TopScoreDocCollector.create(this.hitsPerPage, true);
            this._indexSearcher.search(q, collector);
            this.totalHits = collector.getTotalHits();
            this.hits = collector.topDocs().scoreDocs;
            if (this.hits.length >= 1) {
                int docId = this.hits[0].doc;
                document = this._indexSearcher.doc(docId);
            }
        } catch (IOException | ParseException ex) {
            document = null;
            Logger.getLogger(Query.class.getName()).log(Level.SEVERE, null, ex);
        }
        return document;
    }
}
